package com.aiden.rxjavatest.activity;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.aiden.rxjavatest.GlideApp;
import com.aiden.rxjavatest.HospitalBean;
import com.aiden.rxjavatest.NetWork;
import com.aiden.rxjavatest.R;
import com.aiden.rxjavatest.adapter.CommonAdapter;
import com.aiden.rxjavatest.adapter.ViewHolder;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;
import org.json.JSONObject;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;

public class PracticeActivity extends AppCompatActivity {

    private static final String TAG = "Practice";

    private RecyclerView mRvHospital;
    private CommonAdapter<HospitalBean> mAdapter;
    private Context mContext;
    private Disposable mDisposable, mDisposable2;
    private boolean mIsFromNet = false;
    private List<HospitalBean> mHospitalList = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hospital);
        mContext = this;
        mRvHospital = (RecyclerView) findViewById(R.id.rv_hospital);
        mRvHospital.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new CommonAdapter<HospitalBean>(this, mHospitalList, R.layout.layout_hospital_item) {
            @Override
            protected void convert(ViewHolder holder, HospitalBean hospitalBean, int position) {
                TextView tvName = holder.getView(R.id.tv_name);
                TextView tvAddress = holder.getView(R.id.tv_address);
                ImageView iv = holder.getView(R.id.iv_hospital);
                TextView tvDesc = holder.getView(R.id.tv_desc);
                GlideApp.with(mContext).load(hospitalBean.getImg()).into(iv);
                tvName.setText(hospitalBean.getHosName());
                tvAddress.setText(hospitalBean.getAddr());
                tvDesc.setText(hospitalBean.getInfo());
            }
        };
        mRvHospital.setAdapter(mAdapter);

        practice1();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mDisposable != null && !mDisposable.isDisposed()) {
            mDisposable.dispose();
        }
        if (mDisposable2 != null && !mDisposable2.isDisposed()) {
            mDisposable2.dispose();
        }
    }

    private void practice1() {
        mDisposable = Observable.create(new ObservableOnSubscribe<Response>() {
            @Override
            public void subscribe(ObservableEmitter<Response> emitter) throws Exception {
                Call call = NetWork.getInstance().getClient()
                        .newCall(new Request.Builder().url("http://route.showapi.com/87-60?showapi_appid=71410&showapi_sign=89133959dc8248ee8186bf21fa7c3a68&cityName=深圳").get().build());
                Response response = call.execute();
                emitter.onNext(response);
            }
        }).map(new Function<Response, List<HospitalBean>>() {
            @Override
            public List<HospitalBean> apply(Response response) throws Exception {
                String json = response.body().string();
                JSONObject jsonObject = new JSONObject(json);
                JSONArray jsonArray = jsonObject.optJSONObject("showapi_res_body").optJSONArray("hospitalList");
                return new Gson().fromJson(jsonArray.toString(), new TypeToken<List<HospitalBean>>() {
                }.getType());
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<List<HospitalBean>>() {
                    @Override
                    public void accept(List<HospitalBean> hospitalBeans) throws Exception {
                        Log.e(TAG, "doOnNext save data");
                    }
                })
                .subscribe(new Consumer<List<HospitalBean>>() {
                    @Override
                    public void accept(List<HospitalBean> hospitalBeans) throws Exception {
                        mHospitalList.clear();
                        mHospitalList.addAll(hospitalBeans);
                        mAdapter.notifyDataSetChanged();
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.e(TAG, throwable.getMessage());
                    }
                });
    }

    /**
     * 使用concat实现有缓存数据展示缓存数据，否则再去请求网络数据
     */
    private void practice2() {
        Observable<List<HospitalBean>> cache = Observable.create(new ObservableOnSubscribe<List<HospitalBean>>() {
            @Override
            public void subscribe(ObservableEmitter<List<HospitalBean>> emitter) throws Exception {
                // 获取缓存数据
                List<HospitalBean> hospitalBeans = new ArrayList<>();

                if (hospitalBeans.size() > 0) {
                    // 有缓存数据，发送数据，不执行网络请求数据
                    mIsFromNet = false;
                    emitter.onNext(hospitalBeans);
                } else {
                    // 没有缓存数据，完成缓存发射器，执行网络请求
                    mIsFromNet = true;
                    emitter.onComplete();
                }
            }
        });

        Observable<List<HospitalBean>> net = Observable.create(new ObservableOnSubscribe<List<HospitalBean>>() {
            @Override
            public void subscribe(ObservableEmitter<List<HospitalBean>> emitter) throws Exception {
                // 请求网络数据
                emitter.onNext(new ArrayList<HospitalBean>());
            }
        });

        mDisposable2 = Observable.concat(cache, net)
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<List<HospitalBean>>() {
                    @Override
                    public void accept(List<HospitalBean> hospitalBeans) throws Exception {
                        if (!mIsFromNet) {
                            // 保存数据

                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<HospitalBean>>() {
                    @Override
                    public void accept(List<HospitalBean> hospitalBeans) throws Exception {
                        mHospitalList.clear();
                        mHospitalList.addAll(hospitalBeans);
                        mAdapter.notifyDataSetChanged();
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.e(TAG, throwable.getMessage());
                    }
                });

    }
}
